package cn.newgrand.netcall.ui.leaveword;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Date;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

import org.jivesoftware.resource.Res;
import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.spark.ChatAreaSendField;
import org.jivesoftware.spark.ChatManager;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.ui.ChatInputEditor;
import org.jivesoftware.spark.ui.ContainerComponent;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;
import org.jivesoftware.sparkimpl.settings.local.SettingsManager;

import cn.newgrand.netcall.base.HotKeyRes;
import cn.newgrand.netcall.util.StringUtil;
import cn.newgrand.smackx.specialist.ExpertManager;
import cn.newgrand.smackx.specialist.packet.LeaveWordIQ;

public class LeavewordPanel extends JPanel implements ContainerComponent , PacketListener ,DocumentListener , ActionListener{

	private static final long serialVersionUID = 1L;
	private final TranscriptWindow transcriptWindow;
    //聊天内容输入框
    private final ChatAreaSendField chatAreaSendField;
    private final JSplitPane splitPane;
    private JSplitPane verticalSplit;
    private final JScrollPane textScroller;
    //输入框面板以及表情等工具栏
    private final JPanel bottomPanel;
    private final JPanel chatPanel;
    //底部广告以及发送按钮面板
    private final AdAndSendPanel adSendPanel;
    private JPanel chatWindowPanel;
    private String askerJid;
    private String spid;
    private String askerTrueName;
    
    private KeyAdapter chatEditorKeyListener;
    
    public LeavewordPanel(String askerJid,String spid,String askerTrueName){
    	this.askerJid = askerJid;
    	this.spid = spid;
    	this.askerTrueName = askerTrueName;
//    	PacketFilter iqFilter = new PacketTypeFilter(LeaveWordIQ.class);
//    	PacketFilter fromMatchFilter = new FromMatchesFilter(askerJid);
//    	PacketFilter andFilter = new AndFilter(iqFilter,fromMatchFilter);
		//SparkManager.getConnection().addPacketListener(this, andFilter);
        transcriptWindow = new TranscriptWindow();
        chatPanel = new JPanel(new GridBagLayout());
        splitPane = new JSplitPane();
        bottomPanel = new JPanel();

        adSendPanel = new AdAndSendPanel();
        adSendPanel.getButton().setText("回复留言");
        chatAreaSendField = new ChatAreaSendField("");
        textScroller = new JScrollPane(transcriptWindow);
//        textScroller.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, new Color(250,198,97)));
        textScroller.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1,(Color)UIManager.get("chatRoom.text.pane.border")));

        textScroller.setBackground(transcriptWindow.getBackground());
        textScroller.getViewport().setBackground(Color.white);
        textScroller.setPreferredSize(new Dimension(482,184));
        transcriptWindow.setBackground(Color.white);

        getChatInputEditor().setSelectedTextColor((Color)UIManager.get("ChatInput.SelectedTextColor"));
        getChatInputEditor().setSelectionColor((Color)UIManager.get("ChatInput.SelectionColor"));


        init();

        // Initally, set the right pane to null to keep it empty.
        getSplitPane().setRightComponent(null);

    }
    
 // Setup base layout.
    private void init() {
    	setLayout(new GridBagLayout());

        // Remove Default Beveled Borders
        splitPane.setBorder(null);
        splitPane.setOneTouchExpandable(false);

        // Add Vertical Split Pane
        verticalSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        add(verticalSplit, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));

        verticalSplit.setBorder(null);
        verticalSplit.setOneTouchExpandable(false);

        verticalSplit.setTopComponent(splitPane);

        textScroller.setAutoscrolls(true);

        // Speed up scrolling. It was way too slow.
        textScroller.getVerticalScrollBar().setBlockIncrement(50);
        textScroller.getVerticalScrollBar().setUnitIncrement(20);

        chatWindowPanel = new JPanel();
        chatWindowPanel.setLayout(new GridBagLayout());
        chatWindowPanel.add(textScroller, new GridBagConstraints(0, 10, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
        chatWindowPanel.setOpaque(false);

        // Layout Components
        chatPanel.add(chatWindowPanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 5, 5, 0), 0, 0));

        // Add Chat Panel to Split Pane
        splitPane.setLeftComponent(chatPanel);

        // Add edit buttons to Chat Room
//        editorBar.setOpaque(false);
        chatPanel.setOpaque(false);


//        editorBar.add(new JSeparator(JSeparator.VERTICAL));

        bottomPanel.setOpaque(false);
        splitPane.setOpaque(false);
        bottomPanel.setLayout(new GridBagLayout());
        
        
        //TODO
        add(adSendPanel, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
//		add(adPanel,new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
//      add(sendPanel,new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 20), 0, 0));        
//      sendPanel.setOpaque(false);
//      adPanel.setOpaque(false);
        //
        bottomPanel.add(chatAreaSendField, new GridBagConstraints(0, 1, 5, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 5, 0, 5), 0, 0));
//        bottomPanel.add(editorBar, new GridBagConstraints(0, 0, 5, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));

        // Set bottom panel border
//        bottomPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(197, 213, 230)));
        bottomPanel.setBorder(null);
//        verticalSplit.setOpaque(true);
        verticalSplit.setOpaque(false);

        verticalSplit.setBottomComponent(bottomPanel);
        verticalSplit.setResizeWeight(1.0);
        verticalSplit.setDividerSize(2);

        // Add listener to send button
//        chatAreaButton.getButton().addActionListener(this);
//        adSendPanel.getButton().addActionListener(this);

        // Add Key Listener to Send Field
//        getChatInputEditor().getDocument().addDocumentListener(this);
        
        
        // Add Key Listener to Send Field
        chatEditorKeyListener = new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                checkForEnter(e);
                //resizePreferSizeToLast();
            }

        };
        adSendPanel.getButton().addActionListener(this);
        
        getChatInputEditor().addKeyListener(chatEditorKeyListener);
        
        getChatInputEditor().getDocument().addDocumentListener(this);

//        getChatInputEditor().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("ctrl F4"), "closeTheRoom");
//        getChatInputEditor().getActionMap().put("closeTheRoom", new AbstractAction("closeTheRoom") {
//            public void actionPerformed(ActionEvent evt) {
//                // Leave this chat.
//                closeChatRoom();
//            }
//        });
    }
    
    private void checkForEnter(KeyEvent e) {
    	final LocalPreferences pref = SettingsManager.getLocalPreferences();
    	final KeyStroke keyStroke = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers());
    	// IF there is no body, just return and do nothing
        if (!keyStroke.equals(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.SHIFT_DOWN_MASK)) &&
                e.getKeyChar() == KeyEvent.VK_ENTER && pref.getHotKeySendMessage().equals("Enter")) {
            e.consume();
            sendMessage();
            getChatInputEditor().setText("");
            getChatInputEditor().clear();
            getChatInputEditor().setCaretPosition(0);
//            SparkManager.getWorkspace().getTranscriptPlugin().persistChatRoom(this); 
        }else if (keyStroke.equals(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_DOWN_MASK)) &&
                e.getKeyChar() == KeyEvent.VK_ENTER && pref.getHotKeySendMessage()!="Enter") {
            e.consume();
            sendMessage();
            getChatInputEditor().setText("");
            getChatInputEditor().clear();
            getChatInputEditor().setCaretPosition(0);
//            SparkManager.getWorkspace().getTranscriptPlugin().persistChatRoom(this); 
        }
        else if (keyStroke.equals(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.SHIFT_DOWN_MASK))) {
            final Document document = getChatInputEditor().getDocument();
            try {
                document.insertString(getChatInputEditor().getCaretPosition(), "\n", null);
                getChatInputEditor().requestFocusInWindow();
//                chatAreaButton.getButton().setEnabled(true);
                adSendPanel.getButton().setEnabled(true);
            }
            catch (BadLocationException badLoc) {
                Log.error("Error when checking for enter:", badLoc);
            }
        }
	}
    
    protected void checkForText(DocumentEvent e) {
        final int length = e.getDocument().getLength();
        if (length > 0) {
//            chatAreaButton.getButton().setEnabled(true);
        	adSendPanel.getButton().setEnabled(true);
        }
        else {
//            chatAreaButton.getButton().setEnabled(false);
        	adSendPanel.getButton().setEnabled(false);
        }
//        resizePreferSizeToLast();
//        verticalSplit.setDividerLocation(-1);
    }
    
    public void sendMessage() {
//    	String text = getChatInputEditor().getText();
        String text = getChatInputEditor().getTransText();
        getTranscriptWindow().insertHistoryMessage(spid, text, new Date());
        sendMessage(text);
    }
    
    public void sendMessage(String body){
    	ExpertManager.getInstance(SparkManager.getConnection()).replyLeaveword(askerJid, spid, body);
    }
    
    /**
     * Returns the SendField component.
     *
     * @return the SendField ChatSendField.
     */
    public ChatInputEditor getChatInputEditor() {
        return chatAreaSendField.getChatInputArea();
    }

    /**
     * Returns the chatWindow components.
     *
     * @return the ChatWindow component.
     */
    public TranscriptWindow getTranscriptWindow() {
        return transcriptWindow;
    }
    
    
    public String getAskerJid() {
		return askerJid;
	}

	public void setAskerJid(String askerJid) {
		this.askerJid = askerJid;
	}

	/**
     * Return the splitpane used in this chat room.
     *
     * @return the splitpane used in this chat room.
     */
    public JSplitPane getSplitPane() {
        return splitPane;
    }

	@Override
	public String getTabTitle() {
		return askerTrueName;
	}

	@Override
	public String getFrameTitle() {
		return "ly";
	}

	@Override
	public ImageIcon getTabIcon() {
		return SparkRes.getImageIcon(SparkRes.CONFERENCE_IMAGE_16x16);
	}

	@Override
	public JComponent getGUI() {
		return this;
	}

	@Override
	public String getToolTipDescription() {
		return askerJid;
	}

	@Override
	public boolean closing() {
		ManagerLeavewordPanel.getInstance().closeLeavewordPanel(this);
		return true;
	}
	
	class AdAndSendPanel extends JPanel{
    	private JPanel adChatBottom;
    	private JButton sendButton; 
    	final private JButton chooseButton;
    	final private JPopupMenu popupMenu;
    	final private JCheckBoxMenuItem enterSend;
    	final private JCheckBoxMenuItem ctrlEnterSend;
    	private LocalPreferences pref ;
    	
    	private final DefaultListModel model = new DefaultListModel();
    	
    	public AdAndSendPanel(){
    		setLayout(new GridBagLayout());
    		setOpaque(false);
    		setSize(450,40);
    		
    		enterSend = new JCheckBoxMenuItem();
    		ctrlEnterSend = new JCheckBoxMenuItem();
    		popupMenu = new JPopupMenu();
    		adChatBottom = new JPanel();
    		adChatBottom.setMinimumSize(new Dimension(250,25));
    		adChatBottom.setOpaque(false);
    		
    		sendButton = new JButton();
    		sendButton.setPreferredSize(new Dimension(80,25));
    		chooseButton = new JButton();
    		chooseButton.setIcon(SparkRes.getImageIcon(SparkRes.SEND_HOTKEY_DOWN));
    		chooseButton.setPreferredSize(new Dimension(14,25));
    		chooseButton.setLayout(null);
    		chooseButton.setBorder(null);
//    		chooseButton.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, Color.GRAY));
    		// adChatBottom=new JPanel();
    		sendButton.setContentAreaFilled(true);
    		sendButton.setEnabled(false);
//    		sendButton.setFont(new Font("Dialog", Font.PLAIN, 12));
    		setLayout(new GridBagLayout());
    		add(adChatBottom, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 8, 8,0), 0, 0));
    		add(sendButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(4, 2, 4,0), 0, 0));
    		add(chooseButton, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(4, 2, 3, 25), 0, 0));
//    		add(adChatBottom, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0));
//    		add(sendButton, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 5), 0, 0));
    		// 聊天窗体底部添加广告面板
//    		SwingWorker swingWorker = new SwingWorker() {
//    			public Object construct() {
//    				try {
//    					adChatBottom = AdvertisementManager.getInstance()
//    							.getAdChatBottom();
//    					add(adChatBottom, new GridBagConstraints(0, 0, 1, 1, 0.0,
//    							0.0, GridBagConstraints.WEST,
//    							GridBagConstraints.WEST, new Insets(0, 8, 0, 10),
//    							0, 0));
//    					return true;
//    				} catch (Exception e) {
//    					// TODO: handle exception
//    					e.printStackTrace();
//    					return false;
//    				}
//    			}
//
//    			public void finished() {
//
//    			}
//    		};
//    		swingWorker.start();
    		enterSend.setText(Res.getString("menuitem.hotkey.send.enter"));
    		ctrlEnterSend.setText(Res.getString("menuitem.hotkey.send.ctrlEnter"));
    		popupMenu.add(enterSend);
    		popupMenu.add(ctrlEnterSend);
    		
    		chooseButton.addMouseListener(new MouseAdapter() {
    			@Override
    			public void mouseClicked(MouseEvent e) {
    				// TODO Auto-generated method stub
    				if(e.getSource().equals(chooseButton)){
    					pref = SettingsManager.getLocalPreferences();
    					
    					if(HotKeyRes.SEND_ENTER.equals(pref.getHotKeySendMessage())){
    						enterSend.setSelected(true);
    						ctrlEnterSend.setSelected(false);
    					}else{
    						enterSend.setSelected(false);
    						ctrlEnterSend.setSelected(true);
    					}
    					int x = e.getX();
    					int y = e.getY();
    					popupMenu.show(chooseButton, x, y+15);
    				}
    			}
			});
    		enterSend.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					pref.setHotKeySendMessage(HotKeyRes.SEND_ENTER);
					ctrlEnterSend.setSelected(false);
					commit();
				}
			});
    		ctrlEnterSend.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					pref.setHotKeySendMessage(HotKeyRes.SEND_CTRL_ENTER);
					enterSend.setSelected(false);
					commit();
				}
			});
    		
    	} 
    	
    	/**
    	 * 返回发送按钮
    	 * @return
    	 */
    	public JButton getButton() {
			return sendButton;
		}
    	
        public void commit() {

            SettingsManager.saveSettings();
        }
    }

	@Override
	public void processPacket(final Packet packet) {
		if(packet instanceof LeaveWordIQ){
			LeaveWordIQ leaveword = (LeaveWordIQ)packet;
			String fromUser = leaveword.getFromUser();
			String askerJid = StringUtil.getBaseJid(fromUser);
			getTranscriptWindow().insertMessage(askerJid, leaveword, ChatManager.FROM_COLOR);
		}
	}

	@Override
	public void insertUpdate(DocumentEvent e) {
		checkForText(e);
	}

	@Override
	public void removeUpdate(DocumentEvent e) {
		checkForText(e);
	}

	@Override
	public void changedUpdate(DocumentEvent e) {
		checkForText(e);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		sendMessage();
		getChatInputEditor().clear();
		adSendPanel.getButton().setEnabled(false);
	}

}
